package connexionServer;
//******************************************************************************
// ControleurConnexions.java
// E.Lefrancois 1er janvier 2000
// Projet "Chat"
//******************************************************************************
import java.lang.Thread;
//import java.io.*;
//import java.net.*;
import java.util.*;
import java.lang.System;

import sheepmixView.client.model.Musique;


import LecteurMp3.MultiPlayer;
import bdd.DBConnection;

//==============================================================================
// Objet actif
// Cet objet attend le signal "Fin de connexion", envoye par un objet de type
// "Connexion"
// En reponse a un tel signal, cet objet enleve la connexion correspondante
// de la liste dynamique des connexions.
//
// Toutes les 10 secondes, si aucun signal n'est recu, chaque connexion
// est controlee, puis detruite si inactive (ce qui ne devrait pas arriver
// normalement).
// Cet objet a un acces direct a la liste des connexions
// maintenue par l'objet de type "Serveur" (liste accedee en exclusion mutuelle)
//==============================================================================

public class ControleurConnexions extends Thread {

	private final Integer NB_CREDIT_INITIAL = 5;
	private static DBConnection databaseConnector;
	public  static MultiPlayer jukeBox;
	
	// Variables d'instance
	private Vector<Connexion> a_listeDesConnexions;    // Liste des connexions
	private Hashtable<String, Integer> credits;
	
	public Integer getCredit(String imei) {
		
		if(credits.containsKey(imei)) {
			return credits.get(imei);
		}
		else {
			credits.put(imei, NB_CREDIT_INITIAL);
			return NB_CREDIT_INITIAL;
		}
		
	}
	
	public void decrementerCredit(String imei) {
		credits.put(imei, credits.get(imei) - 1);
	}
	
	public LinkedList<Musique> getTracks(String artist) {
		return databaseConnector.getArtistTracks(artist);
	}
	
	public LinkedList<String> getGenre() {
		return databaseConnector.getGenreList();
	}
	
	public LinkedList<String> getArtist() {
		return databaseConnector.getArtistList();
	}
	
	public LinkedList<String> getArtist(String genre) {
		return databaseConnector.getArtistList(genre);
	}
	
	public LinkedList<Musique> getCurrentPlaylist() {
		return jukeBox.getPlaylist(15);
	}
	
	public Musique getPlayedMusic()  {
		return jukeBox.getPlayedMusic();
	}
	
	public boolean addMusic(int id) {
		Musique mp3 = databaseConnector.getTrack(id);
		if (!jukeBox.contains(mp3)) {
			jukeBox.addUserSong(mp3);
			return true;
		}
		else {
			return false;
		}
	}
	
	public void addPlaylist(LinkedList<String> genres) {
		LinkedList<Musique> list = new LinkedList<Musique>();
		for (int i = 0; i < genres.size(); i++) {
			list.addAll(databaseConnector.getGenreTracks(genres.get(i)));
		}
		Collections.shuffle(list);
		for (int i = 0; i < list.size(); i ++) {
			jukeBox.addSong(list.get(i));
		}
	}
	
	
	
	public void flushPlaylist() {
		jukeBox.removeList();
	}
	
	public void playPlaylist() {
		jukeBox.startPlaylist();
	}
	
	public void stopPlaylist() {
		jukeBox.stopPlaylist();
	}
	
	public boolean pass() {
		return jukeBox.nextOne();
	}
	
	public void load() {
		LinkedList<Musique> list;
		list = databaseConnector.getArtistTracks("Little Boots");
		for (int i = 0; i < list.size(); i ++) {
			jukeBox.addSong(list.get(i));
		}
	}
	
	private static final int DUREE_DE_VEILLE = 10000;
	// Periodicite de controle (msec)

	// Constructeur(s)
	public ControleurConnexions (Vector<Connexion> liste,Hashtable<String, Integer> listeCredits, DBConnection dbc, MultiPlayer m) {
		a_listeDesConnexions = liste;
		credits = listeCredits;
		databaseConnector = dbc;
		jukeBox = m;
		this.start();	// Pour demarrer l'activite
	}

	// Methodes publiques
	public void finDeConnexion (Connexion c) {
		// Fin de la connexion "c"
		this.notify();
	}

	// Activite
	public synchronized void  run () {
		while (true) {
			try {
				this.wait (DUREE_DE_VEILLE);
				// attend le signal "fin de connexion"
				// (au travers d'un signal "notify()")
				// Attend max. 10 sec.
				this.enleveConnexionsInactives();
			}
			catch (InterruptedException e) {
				// Thread interrompu par un autre Thread (au travers
				// de la methode "interrupt" de la classe Thread)
				// Cet evenement ne devrait pas arriver ici.
			}
		}
	}
	
	public void envoyerUpdateMusiqueGUI(LinkedList<Musique> update) {
		Connexion uneConnexion;
		for (int cpt = a_listeDesConnexions.size()-1; cpt >= 0; cpt--) {
			uneConnexion =
					a_listeDesConnexions.elementAt(cpt);
			if (uneConnexion.getImei().equals("sheepGUI")) {
				uneConnexion.envoyerMusiquesAuClient(update);
			}
		}
	}

	// Methodes privees
	private void enleveConnexionsInactives() {
		
		Connexion uneConnexion;
		synchronized (a_listeDesConnexions) {
			for (int cpt = a_listeDesConnexions.size()-1; cpt >= 0; cpt--) {
				uneConnexion =
						a_listeDesConnexions.elementAt(cpt);
				
				if (! uneConnexion.isAlive()) {
					if(uneConnexion.getImei().equals("sheepGUI"));
						jukeBox.deleteObserver(uneConnexion);
						
					a_listeDesConnexions.removeElementAt(cpt);
					System.out.println ("Deconnexion d'un client");
				}
			}
		}
	}
}

